package com.cndw.kungfu.event.once;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;

import com.cndw.kungfu.config.ConstantsChat;
import com.cndw.kungfu.config.ConstantsDailyItem;
import com.cndw.kungfu.config.ConstantsLog;
import com.cndw.kungfu.domain.GoodsFall;
import com.cndw.kungfu.domain.GoodsMode;
import com.cndw.kungfu.domain.Monster;
import com.cndw.kungfu.domain.MonsterDeploy;
import com.cndw.kungfu.domain.Player;
import com.cndw.kungfu.domain.Scene;
import com.cndw.kungfu.domain.Undercity;
import com.cndw.kungfu.ext.LangUtil;
import com.cndw.kungfu.ext.LanguageLib;
import com.cndw.kungfu.ext.NumberProcesser;
import com.cndw.kungfu.ext.TimeProcesser;
import com.cndw.kungfu.model.Context;
import com.cndw.kungfu.model.battle.AiReport;
import com.cndw.kungfu.model.goods.PlayerBoxs;
import com.cndw.kungfu.model.sys.ChatMain;
import com.cndw.kungfu.model.sys.LogServer;
import com.cndw.kungfu.vo.PlayerReceiveVO;

/**
 * 副本扫荡脚本
 * 
 * @author fantadust [9677889@qq.com]
 * @date 2012-2-24 下午2:56:25
 */
public class AiUndercityTask implements Runnable {
	/**
	 * 角色id
	 */
	private long playerId;
	/**
	 * 副本id
	 */
	private int undercityId;
	/**
	 * 执行次数
	 */
	private int aiTimes;
	/**
	 * 当前场景编号
	 */
	private int step = 0;
	private int nowStep = 0;
	/**
	 * 当前轮次
	 */
	private int times = 0;

	private int startTime = 0;

	private int endTime = 0;

	private boolean isFast = false;
	private boolean isSuc = false;

	private ScheduledFuture<?> task;

	private List<AiReport> aiReports = new ArrayList<AiReport>();

	public static final int delay = 120;//单个场景时间 120

	public AiUndercityTask(long playerId, int undercityId, int aiTimes) {
		this.playerId = playerId;
		this.undercityId = undercityId;
		this.aiTimes = aiTimes;
	}

	public int getUndercityId() {
		return undercityId;
	}

	public int getAiTimes() {
		return aiTimes;
	}

	public int getStartTime() {
		return startTime;
	}

	public int getEndTime() {
		return endTime;
	}

	public int getStep() {
		return step;
	}

	public int getTimes() {
		return times;
	}

	public List<AiReport> getAiReports() {
		return aiReports;
	}

	public boolean isSuc() {
		return isSuc;
	}

	public int getNowstep() {
		return nowStep;
	}

	public void runBoos() {

		Undercity undercity = Context.getUndercityServer().getUndercity(undercityId);
		int allStep = undercity.getSceneIdsArr().length;
		startTime = TimeProcesser.getUnixTime();
		endTime = startTime + allStep * aiTimes * delay;

		task = Context.getTimerServer().scheduleAtFixedRate(this, delay);
	}

	public void cancel() {
		if (task != null) {
			task.cancel(false);
			// LogBase.loger.debug(" cancel ");
		}
	}

	public void runFast() {
		do {
			isFast = true;
		} while (runMain());
	}

	@Override
	public void run() {
		runMain();
	}

	public boolean runMain() {
		try {

			Player player = Context.getPlayerServer().getByPlayerId(playerId);
			Undercity undercity = Context.getUndercityServer().getUndercity(undercityId);
			int[] sceneIds = undercity.getSceneIdsArr();

			if (step == 0 || step == sceneIds.length) {
				if (times >= aiTimes) {
					cancel();
					isSuc = true;
					return false;
				}
				step = 0;
				times++;
			}

			if (step == 0) {
				player.getDataInfo().getEveryDay().underCityTimesIncrement(undercityId);
			}

			int sceneId = sceneIds[step];

			// Scene scene = Context.getSceneServer().getSceneById(sceneId);
			// int monsterNums = 0;
			/**
			 * 掉落列表
			 */
			Map<Integer, Integer> failMap = new HashMap<Integer, Integer>();
			int failExp = 0, failAsset = 0;
			List<MonsterDeploy> monsterDeploys = Context.getCacheCenter().getMonsterDeploysBySceneId(sceneId);

			for (MonsterDeploy monsterDeploy : monsterDeploys) {
				List<Integer> monsterIdsList = monsterDeploy.getMonsterIdsList();
				if (monsterIdsList == null || monsterIdsList.size() == 0) {
					continue;
				}
				for (Integer monsterId : monsterIdsList) {
					Monster monster = Context.getUndercityServer().getMonster(monsterId);
					if (monster == null) {
						continue;
					}
					// monsterNums++;
					if (NumberProcesser.isWinning(monster.getAssetR())) {
						failAsset += monster.getAsset();
					}
					failExp += monster.getExp();
					
					if (monster.getBoss() > 0) {
						Context.getTaskServer().notifyToSpark(playerId, monsterId, 1);
					}
					
					List<GoodsFall> goodsFalls = monster.getItemFallDataList();
					if (goodsFalls == null || goodsFalls.isEmpty()) {
						continue;
					}

					for (int i = 0; i < monster.getItemFallMax(); i++) {
						int currentRate = NumberProcesser.mtRand(1000);
						int goodsRate = 0;
						for (GoodsFall e : goodsFalls) {
							GoodsMode goodsMode = Context.getGoodsServer().getModeById(e.getGoodsId());
							if (goodsMode == null) {// 不存在的物品不发送
								continue;
							}
							if (goodsMode.isTaskItem()) {
								continue;
							} else {
								goodsRate += e.getRate();
								if (currentRate <= goodsRate) {
									int num = 1;
									if (failMap.containsKey(e.getGoodsId())) {
										num += failMap.get(e.getGoodsId());
									}
									failMap.put(e.getGoodsId(), num);
									break;
								}
							}
						}
					}
					
				}
			}
			StringBuffer failSB = new StringBuffer();
			Map<Integer, Integer> finalFailMap = new HashMap<Integer, Integer>();
			if (!failMap.isEmpty()) {
				PlayerBoxs playerBoxs = player.getPlayerBoxs();
				for (Map.Entry<Integer, Integer> entry : failMap.entrySet()) {
					int goodsId = entry.getKey();
					int nums = entry.getValue();
					GoodsMode goodsMode = Context.getGoodsServer().getModeById(goodsId);
					if (goodsMode == null) {
						continue;
					}
					int needSize = NumberProcesser.ceil(entry.getValue(), goodsMode.getMaxStack());
					needSize = needSize <= 0 ? 1 : needSize;
					if (!playerBoxs.checkBlack(needSize)) {
						break;
					}
					// 发送道具
					Context.getGoodsServer().giveGoods(playerId, goodsId, nums);
					if (failSB.length() > 0) {
						failSB.append(",");
					}
					failSB.append(goodsMode.getName()).append("*").append(nums);
					finalFailMap.put(goodsId, nums);
					if (goodsMode.isEquiq() && goodsMode.getColor() >= 3) {
						try {
							Scene scene = Context.getSceneServer().getSceneById(sceneId);
							ChatMain.hearsayMessage(
									LanguageLib.get("chat.board.equip", LangUtil.makeNameLink(player), scene.getName(), goodsMode.getName(),
											LangUtil.getColor(goodsMode.getColor())), ConstantsChat.cwGot);
						} catch (Exception e) {
							e.printStackTrace();
						}

					}
				}
			}

			int percentExpAdd = 100;

			if (player.getKnight() != null) {
				percentExpAdd += player.getKnight().getPveExpR();
			}
			failExp = NumberProcesser.percentOnlyAddValue(failExp, percentExpAdd);
			failAsset = NumberProcesser.percentOnlyAddValue(failAsset, NumberProcesser.mtRand(90, 110));

			AiReport aiReport = new AiReport();
			aiReport.setAsset(failAsset);
			aiReport.setExp(failExp);
			aiReport.setFailMap(finalFailMap);
			aiReport.setFailSB(failSB.toString());
			aiReport.setStep(step);
			aiReport.setTimes(times);
			aiReport.setT(TimeProcesser.getUnixTime());

			aiReports.add(aiReport);

			player.alterExp(failExp);
			player.alterAsset(failAsset);

			player.commitSync();

			PlayerReceiveVO receive = new PlayerReceiveVO();
			receive.put(PlayerReceiveVO.RECEIVE_ASSET, failAsset);
			receive.put(PlayerReceiveVO.RECEIVE_EXP, failExp);
			receive.put(PlayerReceiveVO.aiStep, nowStep + 1);

			receive.broadcast(playerId);

			LogServer.recordLog(player, ConstantsLog.battle, 40020, undercity.getName(), step, times, failExp, failAsset, failSB.toString(), isFast);

			// StringBuffer logSB = new StringBuffer();
			// logSB.append(scene.getName()).append(" ").append(monsterNums).append(" ");
			// logSB.append("times").append(":").append(times).append(" ");
			// logSB.append("step").append(":").append(step).append(" ");
			// logSB.append("failAsset").append(":").append(failAsset).append(" ");
			// logSB.append("failExp").append(":").append(failExp).append(" ");

			// LogBase.loger.debug(logSB.toString() + failSB.toString());

			step++;
			nowStep++;

			if (step == sceneIds.length) {
				// 加到每日奖励
				player.getDataInfo().getEveryDay().finishDailyItem(ConstantsDailyItem.singleUndercityItem);
				
				if (times >= aiTimes) {//次数结束了
					cancel();
					isSuc = true;
					return false;
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
		return true;
	}

}
